package jmu.edu.yjc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jmu.edu.yjc.Utils.BeanCopyUtil;
import jmu.edu.yjc.Utils.SecurityUtil;
import jmu.edu.yjc.constants.SystemConstants;
import jmu.edu.yjc.domain.ResponseResult;
import jmu.edu.yjc.domain.entity.Menu;
import jmu.edu.yjc.domain.vo.menu.MenuTreeVo;
import jmu.edu.yjc.domain.vo.menu.MenuVo;
import jmu.edu.yjc.domain.vo.menu.RoleMenuTreeSelectVo;
import jmu.edu.yjc.mapper.MenuMapper;
import jmu.edu.yjc.service.MenuService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 菜单权限表(Menu)表服务实现类
 *
 * @author makejava
 * @since 2023-01-19 16:43:44
 */
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {

    @Override
    public List<String> selectPermsByUserId(Long userId) {
        if(userId==1L){
            //如果是超级管理员返回所有权限
            LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.in(Menu::getMenuType, SystemConstants.MENU_TYPE_MENU,SystemConstants.MENU_TYPE_BUTTON);
            queryWrapper.eq(Menu::getStatus,SystemConstants.STATUS_NORMAL);
            List<Menu> list = list(queryWrapper);
            return list.stream()
                    .map(Menu::getPerms).collect(Collectors.toList());
        }
        //否则返回所具有的权限
        return getBaseMapper().selectPermsByUserId(userId);
    }

    @Override
    public List<MenuVo> selectRouterMenuTreeByUserId(Long userId) {
        MenuMapper menuMapper = getBaseMapper();
        List<Menu> menus = null;
        //判断是否是超级管理员
        //如果是返回符合要求的menu
        if(SecurityUtil.isAdmin()){
            menus = menuMapper.selectAllRouterMenu();
        }else {
            //否则查询当前用户所具有的menu
            menus = menuMapper.selectRouterMenuTreeByUserId(userId);
        }
        return buildMenuVoTree(menus);
    }

    @Override
    public ResponseResult menuList(String menuName, String status) {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.hasText(menuName),Menu::getMenuName,menuName);
        queryWrapper.eq(StringUtils.hasText(status),Menu::getStatus,status);
        queryWrapper.and(wrapper ->{
            wrapper.eq(Menu::getMenuType,SystemConstants.MENU_TYPE_MENU);
            wrapper.or();
            wrapper.eq(Menu::getMenuType,SystemConstants.MENU_TYPE_CATALOG);
        });
        queryWrapper.orderByAsc(Menu::getParentId,Menu::getOrderNum);
        List<Menu> menus = list(queryWrapper);
        List<MenuVo> menuVos = BeanCopyUtil.copyBeanList(menus, MenuVo.class);
        return ResponseResult.okResult(menuVos);
    }

    @Override
    public boolean hasChild(Long menuId) {
        LambdaQueryWrapper<Menu> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Menu::getParentId,menuId);
        return count(queryWrapper) != 0;
    }

    @Override
    public ResponseResult treeselect() {
        List<Menu> menus = list();
        return ResponseResult.okResult(buildMenuTree(menus));
    }
    public List<MenuTreeVo> buildMenuTree(List<Menu> menus){
        List<MenuTreeVo> MenuTreeVos = menus.stream()
                .map(m -> new MenuTreeVo(m.getId(), m.getMenuName(), m.getParentId(), null))
                .collect(Collectors.toList());
        return  MenuTreeVos.stream()
                .filter(o -> o.getParentId().equals(0L))
                .map(o -> o.setChildren(getChildList(MenuTreeVos, o)))
                .collect(Collectors.toList());
    }
    /**
     * 得到子节点列表
     */
    private  List<MenuTreeVo> getChildList(List<MenuTreeVo> list, MenuTreeVo option) {
        List<MenuTreeVo> options = list.stream()
                .filter(o -> Objects.equals(o.getParentId(), option.getId()))
                .map(o -> o.setChildren(getChildList(list, o)))
                .collect(Collectors.toList());
        return options;

    }
    @Override
    public ResponseResult roleMenuTreeselect(Long roleId) {
        List<Menu> menus = list();
        List<MenuTreeVo> menuTreeVos = buildMenuTree(menus);
        List<Long> checkedKeys = getBaseMapper().selectMenuListByRoleId(roleId);
        RoleMenuTreeSelectVo vo = new RoleMenuTreeSelectVo(checkedKeys,menuTreeVos);
        return ResponseResult.okResult(vo);
    }
    private List<MenuVo> buildMenuVoTree(List<Menu> menus) {
        List<MenuVo> menuVos = BeanCopyUtil.copyBeanList(menus, MenuVo.class);
        for (int i = 0; i < menuVos.size(); i++) {
            List<MenuVo> children = new ArrayList<>();
            for (int j = 0; j < menuVos.size(); j++) {
                if(menuVos.get(i).getId().equals(menuVos.get(j).getParentId())){
                    children.add(menuVos.get(j));
                }
            }
            menuVos.get(i).setChildren(children);
        }
        List<MenuVo>  topMenus = new ArrayList<>();
        for (MenuVo menuVo : menuVos) {
            if(menuVo.getParentId()==0L){
                topMenus.add(menuVo);
            }
        }
        return topMenus;
    }
}
